/*
 * Copyright 2005 Lumis EIP Tecnologia da Informação
 */
package lumis.util;

import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.net.URLEncoder;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import lumis.portal.PortalException;
import lumis.portal.authentication.SessionConfig;
import lumis.portal.manager.ManagerFactory;
import lumis.portal.serviceinterface.IServiceInterfaceRequest;
import lumis.portal.serviceinterface.IServiceInterfaceResponse;
import lumis.portal.stability.StableMinor;
import lumis.portal.transaction.PortalTransactionFactory;
import lumis.portal.user.UserConfig;

/**
 * Utility methods for cookies manipulation.
 * @since 4.0.7
 * @version $Revision: 13082 $ $Date: 2011-05-27 16:03:12 -0300 (Fri, 27 May 2011) $
 */
@StableMinor(version = "6.0", sinceVersion = "4.0")
public class CookieUtil
{
	/**
	 * Sets a cookie path according to the Website for the given request.
	 * @param request the request.
	 * @param cookie the cookie.
	 * @see PortalUtil#getWebsiteUri(HttpServletRequest)
	 * @see Cookie#setPath(String)
	 * @since 4.2.0
	 */
	private static void setCookiePath(HttpServletRequest request, Cookie cookie)
	{
		String cookiePath = PortalUtil.getWebsiteUri(request);
		if (cookiePath.length() == 0)
			cookiePath = "/";
		cookie.setPath(cookiePath);
	}

	/**
	 * Given a cookie name, the cookie value if exists in the request object is
	 * returned. If the cookie is not found, a null value is returned
	 * 
	 * @param request the request.
	 * @param response the response.
	 * @param name the cookie name.
	 * @return cookie value
	 * @since 4.0.7
	 */
	public static String getCookie(IServiceInterfaceRequest request, String name)
	{
		return getCookie((HttpServletRequest)request, name);
	}
	
	/**
	 * Given a cookie name, the cookie value if exists in the request object is
	 * returned. If the cookie is not found, a null value is returned
	 * 
	 * @param request the request.
	 * @param response the response.
	 * @param name the cookie name.
	 * @return cookie value
	 * @since 4.0.7
	 */
	public static String getCookie(HttpServletRequest request, String name)
	{
		String cookieValue = null;
		Cookie[] cookies = request.getCookies();

		if (cookies != null)
		{
			for (Cookie cookie : cookies)
			{
				if (cookie.getName().equals(name))
				{
					try
					{
						cookieValue = URLDecoder.decode(cookie.getValue(), "UTF-8");
						break;
					}
					catch (UnsupportedEncodingException e)
					{
						throw new RuntimeException(e);
					}
				}
			}
		}

		return cookieValue;
	}

	/**
	 * Sets a cookie value.
	 * @param request the request.
	 * @param response the response.
	 * @param name the cookie name.
	 * @param value the cookie value.
	 * @since 4.0.7
	 */
	public static void setCookie(IServiceInterfaceRequest request, IServiceInterfaceResponse response, String name, String value)
	{
		setCookie((HttpServletRequest)request, (HttpServletResponse)response, name, value);
	}
	
	/**
	 * Sets a cookie value.
	 * @param request the request.
	 * @param response the response.
	 * @param name the cookie name.
	 * @param value the cookie value.
	 * @since 4.0.7
	 */
	public static void setCookie(HttpServletRequest request, HttpServletResponse response, String name, String value)
	{
		Cookie cookie;
		try
		{
			cookie = new Cookie(name, URLEncoder.encode(value, "UTF-8"));
		}
		catch (UnsupportedEncodingException e)
		{
			throw new RuntimeException(e);
		}
		setCookiePath(request, cookie);
		response.addCookie(cookie);
	}

	/**
	 * Deletes the cookie if it exists in the request.
	 * @param request the request.
	 * @param response the response.
	 * @param name the cookie name.
	 * @since 4.0.7
	 */
	public static void deleteCookie(IServiceInterfaceRequest request, IServiceInterfaceResponse response, String name)
	{
		deleteCookie((HttpServletRequest)request, (HttpServletResponse)response, name);
	}
	
	/**
	 * Deletes the cookie if it exists in the request.
	 * @param request the request.
	 * @param response the response.
	 * @param name the cookie name.
	 * @since 4.0.7
	 */
	public static void deleteCookie(HttpServletRequest request, HttpServletResponse response, String name)
	{
		Cookie[] cookies = request.getCookies();

		if (cookies != null)
		{
			for (Cookie cookie : cookies)
			{
				if (cookie.getName().equals(name))
				{
					cookie.setMaxAge(0);
					setCookiePath(request, cookie);
					response.addCookie(cookie);
					break;
				}
			}
		}
	}
	
	/**
	 * Delete lumis user information cookies.
	 * @param request the request.
	 * @param response the response.
	 * @since 4.0.7
	 */
	public static void deleteLumisUserCookies(IServiceInterfaceRequest request, IServiceInterfaceResponse response)
	{
		deleteLumisUserCookies((HttpServletRequest)request, (HttpServletResponse)response);
	}
	
	/**
	 * Delete lumis user information cookies.
	 * @param request the request.
	 * @param response the response.
	 * @since 4.0.7
	 */
	public static void deleteLumisUserCookies(HttpServletRequest request, HttpServletResponse response)
	{
		deleteCookie(request, response, "lumUserId");
		deleteCookie(request, response, "lumUserName");
		deleteCookie(request, response, "lumUserLogin");
		deleteCookie(request, response, "lumUserEmail");
		deleteCookie(request, response, "lumUserSessionId");
	}
	
	/**
	 * Adds lumis user information cookies.
	 * @param request the request.
	 * @param response the response.
	 * @throws PortalException if it was not possible to obtain the data 
	 * necessary to set the cookies.
	 * @since 4.0.7
	 */
	public static void addLumisUserCookies(IServiceInterfaceRequest request, IServiceInterfaceResponse response) throws PortalException
	{
		addLumisUserCookies((HttpServletRequest)request, (HttpServletResponse)response);
	}
	
	/**
	 * Adds lumis user information cookies.
	 * @param request the request.
	 * @param response the response.
	 * @throws PortalException if it was not possible to obtain the data 
	 * necessary to set the cookies.
	 * @since 4.0.7
	 */
	public static void addLumisUserCookies(HttpServletRequest request, HttpServletResponse response) throws PortalException
	{
		SessionConfig sessionConfig = SessionConfig.getCurrentSessionConfig();
		setCookie(request, response, "lumUserSessionId", sessionConfig.getUserSessionId());

		String userId = sessionConfig.getUserId();
		if(UserConfig.USER_GUEST_ID.equals(userId))
		{
			// set cookies as defined in the guest user, hard-coded for optimization
			// (no problem since guest user may not be edited)
			setCookie(request, response, "lumUserId", UserConfig.USER_GUEST_ID);
			setCookie(request, response, "lumUserName", "Guest");
			setCookie(request, response, "lumUserLogin", "guest");
			if (sessionConfig.getLocale() != null)
				setCookie(request, response, "lumUserLocale", sessionConfig.getLocale().toString());
		}
		else
		{
			ITransaction transaction = PortalTransactionFactory.createTransaction();
			try
			{
				transaction.begin();
				
				// set cookies according to user properties
				UserConfig userConfig = ManagerFactory.getUserManager().get(sessionConfig, userId, transaction); 
				setCookie(request, response, "lumUserId", userConfig.getId());
				setCookie(request, response, "lumUserName", userConfig.getFirstName());
				setCookie(request, response, "lumUserLogin", userConfig.getLogin());
				if (userConfig.getEmail() != null)
					setCookie(request, response, "lumUserEmail", userConfig.getEmail());
				
				if (sessionConfig.getLocale() != null)
					setCookie(request, response, "lumUserLocale", sessionConfig.getLocale().toString());
				
				transaction.commit();
			}
			finally
			{
				transaction.dispose();
			}
		}
	}
	
	/**
	 * Delete lumis standard cookies. Also deletes the lumis user information
	 * cookies.
	 * @param request the request.
	 * @param response the response.
	 * @since 4.0.7
	 */
	public static void deleteLumisStandardCookies(IServiceInterfaceRequest request, IServiceInterfaceResponse response)
	{
		deleteLumisStandardCookies((HttpServletRequest)request, (HttpServletResponse)response);
	}
	
	/**
	 * Delete lumis standard cookies.  Also deletes the lumis user information
	 * cookies.
	 * @param request the request.
	 * @param response the response.
	 * @since 4.0.7
	 */
	public static void deleteLumisStandardCookies(HttpServletRequest request, HttpServletResponse response)
	{
		deleteLumisUserCookies(request, response);
		deleteCookie(request, response, "lumMode");
		deleteCookie(request, response, "lumRequestedPage");
	}	
}
